# +----------------------------------------------------------------------
# | ChatWork智能聊天办公系统
# +----------------------------------------------------------------------
# | 软件声明: 本系统并非自由软件,未经授权任何形式的商业使用均属非法。
# | 版权保护: 任何企业和个人不允许对程序代码以任何形式任何目的复制/分发。
# | 授权要求: 如有商业使用需求,请务必先与版权所有者取得联系并获得正式授权。
# +----------------------------------------------------------------------
# | Author: ChatWork Team <2474369941@qq.com>
# +----------------------------------------------------------------------
import logging
from typing import List
from fastapi import APIRouter, Request, Depends
from fastapi.responses import JSONResponse
from config import get_settings
from hypertext import R, response_json
from common.enums.pay import PayEnum
from common.models.market import RechargeOrderModel
from common.models.market import SubscribeOrderModel
from plugins.paid.wxpay import WxpayService
from plugins.paid.ailpay import AlipayService
from apps.api.schemas import payment_schema as schema
from apps.api.service.payment_service import PaymentService
from apps.api.service.payNotify_service import PayNotifyService

router = APIRouter(prefix="/payment", tags=["支付接口"])

logger = logging.getLogger(__name__)


@router.get("/pay_way", summary="支付方式", response_model=R[List[schema.PayWayListVo]])
@response_json
async def pay_way():
    return await PaymentService.pay_way()


@router.get("/listen", summary="支付监听", response_model=R[schema.PayListenVo])
@response_json
async def listen(request: Request, params: schema.PayListenIn = Depends()):
    user_id: int = int(request.state.user_id)
    return await PaymentService.listen(params.attach, params.order_id, user_id)


@router.post("/prepay", summary="预支付下单", response_model=R)
@response_json
async def prepay(request: Request, params: schema.PayPrepayIn):
    terminal: int = request.state.terminal
    return await PaymentService.prepay(terminal, params)


@router.api_route("/notify_mnp", summary="微信支付回调", methods=["POST", "GET"], operation_id="mnp")
async def notify_mnp_callback(request: Request):
    headers = request.headers
    try:
        debug = get_settings().APP_DEBUG
        if debug and request.client.host == "127.0.0.1":
            # 本地调试
            data = await request.json()
            result = {
                "event_type": "TRANSACTION.SUCCESS",
                "resource": {
                    "attach": data.get("attach", "subscribe"),
                    "out_trade_no": data.get("out_trade_no"),
                    "transaction_id": "800000000999886"
                }
            }
        else:
            # 线上正式
            body = await request.body()
            _wxpay = await WxpayService.wxpay()
            result = _wxpay.callback(headers, body)
            if result is None:
                logging.error("微信支付回调解密失败,请检查证书密钥")
                logger.error(body)
    except Exception as e:
        message = f"微信支付回调失败: {e}"
        logging.error(message)
        return JSONResponse(content={"code": "FAILED", "message": message})

    try:
        if result and result.get("event_type") == "TRANSACTION.SUCCESS":
            # 回调数据
            resp = result.get("resource")
            attach: str = resp.get("attach")
            out_trade_no: str = resp.get("out_trade_no")
            transaction_id: str = resp.get("transaction_id")

            # 查找订单
            status = False
            if attach == "recharge":
                order = await RechargeOrderModel.filter(order_sn=out_trade_no).first()
                if not order or order.pay_status == PayEnum.PAID_OK:
                    status = True
            elif attach == "subscribe":
                order = await SubscribeOrderModel.filter(order_sn=out_trade_no).first()
                if not order or order.pay_status == PayEnum.PAID_OK:
                    status = True

            # 处理订单
            if not status:
                await PayNotifyService.handle(attach, out_trade_no, transaction_id)
            return JSONResponse(content={"code": "SUCCESS", "message": "成功"})
        else:
            return JSONResponse(content={"code": "FAILED", "message": "失败"})
    except Exception as e:
        message = f"支付处理失败: {e}"
        logging.error(f"微信支付处理失败: {str(e)}")
        return JSONResponse(content={"code": "FAILED", "message": message})


@router.api_route("/notify_ali", summary="支付宝的回调", methods=["POST", "GET"], operation_id="ali")
async def notify_ali_callback(request: Request):
    try:
        data = await request.json()
        signature = data.pop("sign")

        _alipay = await AlipayService.alipay()
        success = _alipay.verify(data, signature)
        if success and data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED"):
            # 回调数据
            attach: str = data.get("passback_params")
            out_trade_no: str = data.get("out_trade_no")
            transaction_id: str = data.get("trade_no")

            # 查找订单
            status = False
            if attach == "order":
                pass
            elif attach == "recharge":
                order = await RechargeOrderModel.filter(order_sn=out_trade_no).first()
                if not order or PayEnum.PAID_OK == order.pay_status:
                    status = True
            elif attach == "subscribe":
                order = await SubscribeOrderModel.filter(order_sn=out_trade_no).first()
                if not order or order.pay_status == PayEnum.PAID_OK:
                    status = True

            # 处理订单
            if not status:
                await PayNotifyService.handle(attach, out_trade_no, transaction_id)
            return "success"
        else:
            return "fail"
    except Exception as e:
        logging.error(f"支付支付回调处理失败: {str(e)}")
